Skip to content

feat(mcp): adopt agent's newer copies of the eleven shared Core\Mcp classes - #20

Merged
Snider merged 2 commits into
mainfrom
feat/adopt-agent-mcp-versions
Aug 8, 2026
Merged

feat(mcp): adopt agent's newer copies of the eleven shared Core\Mcp classes#20
Snider merged 2 commits into
mainfrom
feat/adopt-agent-mcp-versions

Conversation

@Snider

@Snider Snider commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Step 1 of 3 in letting dappcore/agent consume this package instead of forking it. Step 2 is agent taking the composer dependency and deleting its local copies; step 3 turns the agent MCP server on.

Why these, and why this direction

Eleven classes exist in both repos under the same Core\Mcp namespace, because agent maps Core\Mcp\ onto its own php/Mcp/ too. Public API is identical on all eleven — same methods, same constants. Every difference is protected helpers: this package prefixes them with get (getStateKey, getCacheKey, getRegisteredServers) where agent doesn't, and agent extracts a few more.

Provenance settles the direction:

date provenance
this package 2026-03-09 initial commit
agent 2026-04-25 "implement extended RFC services + transport"
agent 2026-04-27 "address CodeRabbit + SonarCloud findings"

Agent's are the downstream, newer, reviewed copies. So they come upstream rather than being overwritten by ours — SPOR with best-version-wins, not first-writer-wins.

I chased the one candidate for the opposite direction: OpenApiGenerator::buildSchemas exists only here. Not lost — agent emits the identical schemas block inline inside buildComponents rather than through an extracted helper. Nothing this side had that agent doesn't.

AX-8 verified before copying

None of the eleven imports Core\Mod\Agentic. Their only non-framework imports are Core\Tenant, Core\Mod\Content and Laravel\Mcp — all already used here. php-content is now declared for the first time: ContentResource has always imported Core\Mod\Content\Models\ContentItem without it appearing in composer.json.

CircuitBreaker arrives with its namespace normalised from the braced namespace X { … } form — the only file in either repo using it.

A correction to #19

That PR was titled "stop importing the consumer" and it introduced one. Running pint over the changed files let fully_qualified_strict_types rewrite the inline \Core\Mod\Agentic\Services\AgentToolRegistry::class in executeTool into a top-of-file use.

The coupling never changed — it's still a guarded, late-bound app()->bound() lookup that autoloads nothing — but the source did, and the claim in that PR body was wrong as written. It's now a string literal, which expresses the late binding honestly and which no formatter will promote into an import.

Verification

  • Suite unchanged: 21 failed, 299 passed — identical to main
  • SPDX headers arrive with the files: 13 of 132, from 2
  • No Core\Mod\Agentic import anywhere in php/src/ after linting (checked post-pint, given the above)

🤖 Generated with Claude Code
Co-Authored-By: Virgil virgil@lethean.io

…lasses

Step 1 of letting dappcore/agent consume this package instead of forking it.

Eleven classes exist in both repos under the same Core\Mcp namespace, because
agent maps Core\Mcp\ onto its own php/Mcp/ as well. The public API is identical
on all eleven — same methods, same constants — and every difference is in
protected helpers: this package prefixes them with get (getStateKey,
getCacheKey, getRegisteredServers) where agent does not, and agent extracts a
few more.

Provenance settles which way to merge. These files date from this package's
2026-03-09 initial commit; agent's landed 2026-04-25 as "implement extended RFC
services + transport" and were then hardened on 2026-04-27 by "address
CodeRabbit + SonarCloud findings". Agent's are the downstream, newer, reviewed
copies, so they come upstream rather than being overwritten by ours — SPOR
with best-version-wins, not first-writer-wins.

Chased the one candidate for the other direction: OpenApiGenerator::
buildSchemas exists only here. It is not lost — agent emits the identical
schemas block inline inside buildComponents rather than through an extracted
helper. No behaviour only this side had.

AX-8 verified before copying, not assumed: none of the eleven imports
Core\Mod\Agentic. Their only non-framework imports are Core\Tenant,
Core\Mod\Content and Laravel\Mcp, all of which this package already uses.
php-content is now declared for the first time — ContentResource has always
imported Core\Mod\Content\Models\ContentItem without it being in composer.json.

CircuitBreaker arrives with its namespace normalised from the braced
`namespace X { ... }` form, which was the only file in either repo using it.

One correction to #19, which I got wrong. That PR was titled "stop importing
the consumer" and it introduced one: running pint over the changed files let
fully_qualified_strict_types rewrite the inline
\Core\Mod\Agentic\Services\AgentToolRegistry::class in executeTool into a
top-of-file use statement. The coupling never changed — it is still a guarded,
late-bound app()->bound() lookup that autoloads nothing — but the source did,
and the claim in that PR body was wrong as written. It is now a string literal,
which expresses the late binding honestly and which no formatter will promote
into an import.

SPDX headers come across with the files: 13 of 132 files now carry one, from 2.

Suite unchanged: 21 failed, 299 passed.

Co-Authored-By: Virgil <virgil@lethean.io>
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@Snider, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 57 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4e6b7bda-9fe0-4015-bea9-98494808f034

📥 Commits

Reviewing files that changed from the base of the PR and between ccc8a1c and 1440329.

⛔ Files ignored due to path filters (1)
  • composer.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • composer.json
  • php/src/Mcp/Controllers/McpApiController.php
  • php/src/Mcp/Exceptions/CircuitOpenException.php
  • php/src/Mcp/Resources/AppConfig.php
  • php/src/Mcp/Resources/ContentResource.php
  • php/src/Mcp/Resources/DatabaseSchema.php
  • php/src/Mcp/Services/CircuitBreaker.php
  • php/src/Mcp/Services/DataRedactor.php
  • php/src/Mcp/Services/McpHealthService.php
  • php/src/Mcp/Services/McpMetricsService.php
  • php/src/Mcp/Services/McpWebhookDispatcher.php
  • php/src/Mcp/Services/OpenApiGenerator.php
  • php/src/Mcp/Services/ToolRateLimiter.php

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Snider added a commit that referenced this pull request Aug 8, 2026
TestBridge_NewBridge_Bad has failed on main since 1523144, which made
NewBridge apply cfg.WithDefaults() so a zero Config cannot leave
ReconnectInterval at 0 — connectLoop's min(delay*2, max) backoff would stay
pinned at zero and reconnect in a tight loop. The fix was right. The test was
left asserting the behaviour the fix removed:

    AssertEqual(t, "", bridge.cfg.LaravelWSURL)
    want="" got="ws://localhost:9876/ws"

So the assertion has been describing the bug rather than the contract, and
every push to main since has been red on it.

It now asserts what NewBridge guarantees: a zero Config comes back defaulted,
with a URL, a workspace root, and both reconnect intervals non-zero — the
property the change existed to establish, rather than the one string it
happened to set.

Not caused by #20, which is red for this and touches no Go at all:
its fourteen files are php/ plus composer.json and composer.lock.

go test ./... now passes for the whole module.
@Snider
Snider merged commit 9ac5555 into main Aug 8, 2026
3 of 4 checks passed
@codecov

codecov Bot commented Aug 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant